package com.wf.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wf.dto.FileDTO;
import com.wf.exception.ApartmentException;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * 身份证识别工具类，提供从百度云获取用户身份证信息的功能
 * 通过调用百度云OCR API，识别并返回身份证上的用户信息
 *
 * @author mpk
 * @since 2024/8/30 10:10:21
 */
@Component
@Slf4j
public class IdentificationUtil {

    // 百度云API的Key
    @Value("${baiduyun.api-key}")
    private String appKey;

    // 百度云API的Secret Key
    @Value("${baiduyun.secret-key}")
    private String secretKey;

    /**
     * 通过百度云OCR服务，识别并获取用户身份证信息
     *
     * @param file 身份证图片文件的字节数组
     * @param idCardSide 身份证的面（正面或反面）
     * @return 包含用户信息的Map，如姓名、民族、地址、身份证号和性别
     * @throws IOException 如果文件读取发生错误
     */
    public Map<String, Object> getUserInfo(byte[] file, String idCardSide) throws IOException, ApartmentException {
        HashMap<String, Object> map = new HashMap<>();
        map.put("id_card_side", idCardSide);
        map.put("image", getFileContentAsBase64(file));
        String post = HttpUtil.post("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + getAccessToken(), map);
        log.info("post = {}", post);
        HashMap<String, Object> userInfo = null;
        if (StrUtil.equals(idCardSide, "front")) {
            userInfo = getUserMap(post);
        }else if(StrUtil.equals(idCardSide, "back"))
        {
            JSONObject jsonObject = JSONUtil.parseObj(post);
            if (ObjectUtil.isNotEmpty(jsonObject.get("words_result")) ) {

            }else {
                throw new ApartmentException("身份证识别失败");
            }
        }

        return userInfo;
    }

    /**
     * 通过百度云OCR服务，识别并获取用户身份证信息
     *
     * @param fileDTO 身份证图片文件的字节数组
     * @return 包含用户信息的Map，如姓名、民族、地址、身份证号和性别
     */
    public Map<String, Object> getUserInfoByBase64(FileDTO fileDTO) throws ApartmentException {
        HashMap<String, Object> map = new HashMap<>();
        map.put("id_card_side", fileDTO.getIdCardSide());
        map.put("image", fileDTO.getFile());
        String post = HttpUtil.post("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + getAccessToken(), map);
        log.info("post = {}", post);
        HashMap<String, Object> userInfo = null;
        if (StrUtil.equals(fileDTO.getIdCardSide(), "front")) {
            userInfo = getUserMap(post);
        }

        return userInfo;
    }

    @NotNull
    private HashMap<String, Object> getUserMap(String post) throws ApartmentException {
        HashMap<String, Object> userInfo;
        JSONObject jsonObject = JSONUtil.parseObj(post);
        userInfo = new HashMap<>();
        if (ObjectUtil.isNotEmpty(jsonObject.get("words_result")) ) {
            JSONObject wordsResult = jsonObject.getJSONObject("words_result");
            JSONObject nameResult = wordsResult.getJSONObject("姓名");
            String realName = (String) nameResult.get("words");
            JSONObject ethnicGroupResult = wordsResult.getJSONObject("民族");
            String ethnicGroup = (String) ethnicGroupResult.get("words");
            JSONObject addressResult = wordsResult.getJSONObject("住址");
            String address = (String) addressResult.get("words");
            JSONObject idCardResult = wordsResult.getJSONObject("公民身份号码");
            String idCard = (String) idCardResult.get("words");
            JSONObject genderResult = wordsResult.getJSONObject("性别");
            String gender = (String) genderResult.get("words");
            userInfo.put("realName", realName);
            userInfo.put("ethnicGroup", ethnicGroup);
            userInfo.put("address", address);
            userInfo.put("idCard", idCard);
            userInfo.put("gender", gender);
        }else
        {
            throw new ApartmentException("身份证识别失败");
        }
        return userInfo;
    }

    /**
     * 获取文件的Base64编码
     *
     * @param b 文件的字节数组
     * @return 文件内容的Base64编码字符串
     * @throws IOException 如果文件读取发生错误
     */
    static String getFileContentAsBase64(byte[] b) throws IOException {
        return Base64.getEncoder().encodeToString(b);
    }

    /**
     * 使用应用的API Key和Secret Key从百度云获取访问令牌
     *
     * @return 访问百度云API所需的访问令牌
     */
    public String getAccessToken() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("grant_type", "client_credentials");
        map.put("client_id", appKey);
        map.put("client_secret", secretKey);
        String post = HttpUtil.post("https://aip.baidubce.com/oauth/2.0/token", map);
        JSONObject jsonObject = JSONUtil.parseObj(post);
        return (String) jsonObject.get("access_token");
    }
}
